package cn.backflow.data.service;

import cn.backflow.data.entity.BaseEntity;
import cn.backflow.data.pagination.Page;
import cn.backflow.data.pagination.PageRequest;
import org.springframework.dao.DataAccessException;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import java.util.Map;


public interface BaseService<E extends BaseEntity, PK extends Serializable> {

    /**
     * 按主键获取对象
     *
     * @param id 主建
     */
    E getById(PK id) throws DataAccessException;

    /**
     * 查询所有记录
     *
     * @param parameter 查询参数(实体或Map)
     */
    List<E> findAll(Object parameter) throws DataAccessException;

    /**
     * 查找mapKey与实体映射的 Map集合
     *
     * @param parameter 查询参数(实体或Map)
     * @param mapKey    要映射到Map的key, 应为实体的某个属性名
     */
    Map<Comparable, E> findMap(Object parameter, String mapKey);

    /**
     * 分页查询
     *
     * @param pr 分页查询请求
     */
    Page<E> findPage(PageRequest pr);

    /**
     * 检查某属性是否唯一
     *
     * @param uniqueProperty 要检查唯一的属性名
     */
    boolean isUnique(String uniqueProperty) throws DataAccessException;

    /**
     * 直接执行SQL语句
     *
     * @param sql SQL语句
     */
    @Transactional
    Object excute(String sql) throws DataAccessException;

    /**
     * 插入数据
     */
    @Transactional
    int save(E entity) throws DataAccessException;

    /**
     * 更新数据
     */
    @Transactional
    int update(E entity) throws DataAccessException;

    /**
     * 选择性更新数据
     */
    @Transactional
    int updateSelective(E entity);

    /**
     * 批量选择性更新数据
     */
    @Transactional
    int updateSelectiveBatch(List<E> entities);

    /**
     * 根据id检查是否插入或是更新数据
     */
    @Transactional
    int saveOrUpdate(E entity) throws DataAccessException;

    /**
     * 按主键删除
     *
     * @param id 主键
     */
    @Transactional
    int deleteById(PK id) throws DataAccessException;

    /**
     * 按主键集合批量删除
     *
     * @param pks 主键集合
     */
    @Transactional
    int deleteBatch(Collection<PK> pks) throws DataAccessException;
}